import numpy

import pdv
import curve


##parses and calculates mathematical input for curves, then updates plot##
def parsemath(line, plotlist, commander, xdomain):
    line = line.replace('+', ' + ')
    line = line.replace('-', ' - ')
    line = line.replace('*', ' * ')
    line = line.replace('/', ' / ')
    line = line.replace('(', ' ( ')
    line = line.replace(')', ' ) ')
    line = line.split()
    sendline = ''
    for val in line:
        dex = None
        if(val[0] == '@'):
            dex = int(val[1:])
            sendline += ' plotlist['+str(dex)+'] '
        elif(len(val) == 1 and ord(val.upper()) <= ord('Z') and ord(val.upper()) >= ord('A')):
            dex = ord(val.upper()) - ord('A')
            sendline += ' plotlist['+ str(dex) +'] '
        else:
            sendline += val
    sendline = sendline.lstrip()
    #if(sendline[0] == '-'): #negation case
    #    zeroc = curve.Curve('0','0')
    #    zeroc.x = numpy.array([xdomain[0]-1, xdomain[1]+1])
    #    zeroc.y = numpy.array([0, 0])
    #    sendline = 'zeroc ' + sendline
    #print sendline
    c = eval(sendline)
    c.name = ' '.join(line).replace('commander.', '').title()
    c.plotname = commander.getcurvename()
    if(c.x == None or len(c.x) < 2):
        print 'error: curve overlap is not sufficient'
        return 0
    if(c.plotname[:1] != '@' and ord(c.plotname) >= ord('A') and ord(c.plotname) <= ord('Z')):
        plotlist.insert((ord(c.plotname) - ord('A')), c)
    else:
        plotlist.insert(int(c.plotname[1:]-1), c)
    return c
    #pultry.updateplot()
    

##get a full list of arguments from compact list or mixed notation (ex 4:11)##
def getnumberargs(line, filelist):
    line = line.split(':')
    arglist = ''
    if(len(line) > 1):
        for i in range(len(line)):
            line[i] = line[i].strip()
        if(len(line[0].split()) > 1):   #check for non list args
            nolist = line[0].split()
            nolist.pop(-1)
            nolist = ' '.join(nolist)
            arglist += nolist + ' '
        for i in range(len(line)-1):
            if(i > 0):
                if(len(line[i].split()) > 2):   #check for non list args
                    nolist = line[i].split()
                    nolist.pop(-1)
                    nolist.pop(0)
                    nolist = ' '.join(nolist)
                    arglist += nolist + ' '
            start = line[i].split()[-1]
            end = line[i+1].split()[0]
            if(len(start.split('.')) > 1):
                filedex = ord(start[0].upper()) - ord('A')
                start = start.split('.')[-1]
                if(filedex != 0):
                    for f in range(filedex):
                        start = str(int(start) + filelist[f][1])
            if(len(end.split('.')) > 1):
                filedex = ord(end[0].upper()) - ord('A')
                end = end.split('.')[-1]
                if(filedex != 0):
                    for f in range(filedex):
                        end = str(int(end) + filelist[f][1])
            args = ''
            delta = int(end) - int(start)
            if delta >= 0:
                step = 1
            else:
                step = -1
            for j in xrange(int(start), int(start) + delta + step, step):
                args += str(j) + ' '
            arglist += args + ' '
        if(len(line[-1].split()) > 1):   #check for non list args
            nolist = line[-1].split()
            nolist.pop(0)
            nolist = ' '.join(nolist)
            arglist += nolist + ' '
    return arglist


##get a full list of arguments from compact list or mixed notation (ex a:d)##
def getletterargs(line):
    line = line.split(':')  #begin arduous list parsing
    arglist = ''
    if(len(line) > 1):
        for i in range(len(line)):
            line[i] = line[i].strip()
        if(len(line[0].split()) > 1):   #check for non list args
            nolist = line[0].split()
            nolist.pop(-1)
            nolist = ' '.join(nolist)
            arglist += nolist + ' '
        for i in range(len(line)-1):
            if(i > 0):
                if(len(line[i].split()) > 2):   #check for non list args
                    nolist = line[i].split()
                    nolist.pop(-1)
                    nolist.pop(0)
                    nolist = ' '.join(nolist)
                    arglist += nolist + ' '
            start = line[i].split()[-1].upper()
            if(start[0] == '@'):
                start = int(start[1:])
            else:
                start = ord(start[0]) - ord('A')
            end = line[i+1].split()[0].upper()
            if(end[0] == '@'):
                end = int(end[1:])
            else:
                end = ord(end[0]) - ord('A')
            args = ''
            for j in range(int(end)-int(start)+1):
                if(j+int(start) > 25):
                    args += '@' + str(j+int(start)) + ' '
                else:
                    args += chr(j+int(start) + ord('A')) + ' '
            arglist += args + ''
        if(len(line[-1].split()) > 1):   #check for non list args
            nolist = line[-1].split()
            nolist.pop(0)
            nolist = ' '.join(nolist)
            arglist += nolist + ' '  #end arduous list parsing
    return arglist
        

##truncate a string to given length##
def truncate(string, size):
    if(len(string) > size):
        string = string[:size]
    return string


##interpolate to find y values at given x values##
def interpol(targetx, referencex, referencey):
    tx = numpy.sort(targetx).tolist()
    refx = numpy.sort(referencex).tolist()
    refy = referencey
    
    if(len(refx) != len(refy) or len(tx) == 0 or len(refx) == 0):
        return None, None
    
    xout = []
    yout = []
    
    tptr = 0
    rptr = 0
    while(True):
        #print tptr, rptr
        skip = 0
        if(tx[tptr] > refx[rptr]):
            rptr = rptr + 1
        elif(tx[tptr] < refx[rptr]):
            tptr = tptr + 1
        else:
            xout.append(tx[tptr])
            yout.append(refy[rptr])
            tptr = tptr + 1
            rptr = rptr + 1
        
        if(tptr >= len(tx) or rptr >= len(refx)):
            break
        
        if(refx[rptr] > tx[tptr]):
            lower = refx[rptr-1], refy[rptr-1]
            upper = refx[rptr], refy[rptr]
            
            m = (upper[1] - lower[1])/(upper[0] - lower[0])
            b = -m*lower[0] + lower[1]
            
            yout.append(m*tx[tptr] + b)
            xout.append(tx[tptr])
    return numpy.array(xout), numpy.array(yout)
